import Link from './components/link.js';
import View from './components/view.js';
import createRouteMap from './create-route-map.js';
import createMatchRoute from './utils/index.js';
import HashRouter from './mode/Hash.js';
import HistoryRouter from './mode/History.js';


class VueRouter {
  static _Vue = null;

  constructor(options) {
    this.mode = options.mode || "hash";
    this.history = Object.create(null);
    // if ("hash" === this.mode) {
    //   this.history = new HashRouter(this);
    // } else {
    //   this.history = new HistoryRouter(this);
    // }

    const { pathname, hash }= location;
    let initRoute;
    if ("hash" === this.mode) {
      location.hash = hash || '/';
      initRoute = location.hash.substr(1);
    } else {
      initRoute = pathname;
    }

    this.options = options;

    this.data = Object.create(null);
    VueRouter._Vue.util.defineReactive(this.data, "current", initRoute);

    // this.data = VueRouter._Vue.observable({
    //   current: initRoute
    // });

    this.routeList = [];
    this.routeMap = Object.create(null);
  }

  /**
   * 定义install函数
   * 方式一
   * @param {Vue} Vue
   */
  static install(Vue) {
    if (VueRouter.install.installed) return;
    VueRouter._Vue = Vue;
    VueRouter.install.installed = true;

    Vue.mixin({
      beforeCreate() {
        if (this.$options.router) {
          // Vue实例执行逻辑
          VueRouter._Vue.prototype.$router = this.$options.router;
          this.$options.router.init();
        } else if (this.$options.parent && this.$options.parent.$router) {
          // Vue组件执行逻辑
          this.$router = this.$options.parent.$router;
        }
      }
    })
  }

  init() {
    this.createRouteMap();
    this.initComponents(VueRouter._Vue);
    this.initEvent();
  }

  createRouteMap() {
    const {
      routeList,
      routeMap
    } = createRouteMap(this.options.routes);
    
    this.routeMap = routeMap;
    this.routeList = routeList;
  }

  initComponents(Vue) {
    Vue.component('router-link', Link);

    Vue.component('router-view', View);
  }

  initEvent() {
    window.addEventListener('popstate', (e) => {
      this.data.current = location.pathname;
      // this.matched = createMatchRoute(this.routeMap[this.data.current], this.data.current);
    });
    window.addEventListener('hashchange', (e) => {
      this.data.current = location.hash.substr(1);
      // this.matched = createMatchRoute(this.routeMap[this.data.current], this.data.current);
    });
  }
}

export default VueRouter;
